上一节我们学习了 Nuxt3 处理异常的各种方法,本讲我们将结合项目开发实践给大家介绍一些比较常用的配置项,为以后的项目开发做准备,本节涉及内容如下:
- 几种配置方式对比;
- 开发常用配置;
- 配置 Meta 信息。
# 几种配置方式对比
Nuxt 应用中有三种常见的配置方式:
- nuxt.config.ts:覆盖或扩展默认 Nuxt 配置;
- app.config.ts:配置公共变量;
- 外部配置文件:配置项目中其他方面。
# nuxt.config.ts
Nuxt 其实有一套默认配置,能够应付大部分需要。但是当我们需要覆盖或扩展默认 Nuxt 配置时,我们就可以在项目根目录下创建一个 nuxt.config.ts,它默认导出 defineNuxtConfig() 的执行结果,再和默认 nuxt 配置合并并最终生效,例如我们前面增加的模块配置:
arduino
复制代码export default defineNuxtConfig({
modules: [
"@nuxtjs/tailwindcss",
"@pinia/nuxt",
"@huntersofbook/naive-ui-nuxt",
],
});
我们会在后面演示一些开发中比较常见的配置方法。
# app.config.ts
如果需要配置一些项目需要的公共变量,可以在项目根目录创建 app.config.ts,这些变量是响应式的,不仅在运行时可以访问,还可以改变。例如下面的配置范例:
php
复制代码export default defineAppConfig({
title: 'Hello Nuxt',
theme: {
dark: true,
colors: {
primary: '#ff0000'
}
}
})
实际上,nuxt.config.ts 中有个 appConfig 选项可以起到相同的作用。
访问 app.config.ts 中的变量:
ini
复制代码 const appConfig = useAppConfig()
# 范例:根据配置项设置黑暗模式
创建 ~/pages/config.vue,根据 app.config.ts 中的配置控制黑暗模式和标题。
ini
复制代码<template>
<div :class="{ dark: appConfig.theme.dark }">
<p
class="bg-blue-300 dark:bg-slate-600 dark:text-slate-200"
@click="appConfig.title = 'hello'"
>
appConfig: {{ appConfig.title }}
</p>
<label>
dark mode:
<NSwitch id="toggle" v-model:value="appConfig.theme.dark" />
</label>
</div>
</template>
<script setup lang="ts">
const appConfig = useAppConfig();
</script>
需要额外开启 tailwind 黑暗模式,tailwind.config.js:
java 复制代码module.exports = { darkMode: 'class', }
效果如下:

# 外部配置文件
Nuxt 只认 nuxt.config.ts,因此一些大家熟悉的独立配置文件会被忽略,作为替代,nuxt.config.ts 中会有对应的配置项,我们来看一下都有哪些:
nitro.config.ts:不能使用,使用 nitro 选项配置;postcss.config.js:不能使用,使用 postcss 选项配置;vite.config.ts:不能使用,使用 vite 选项配置;webpack.config.ts:不能使用,使用 webpack 选项配置。
当然,还有一些配置文件依然可以使用:
- tsconfig.json;
- .eslintrc.js;
- .prettieerrc.json;
- .stylelintrc.json;
- tailwind.config.js;
- vitest.config.js。
# 开发常用配置
下面我们演示一些开发中非常常用的配置项,掌握它们对我们开发很有帮助。
# 配置打包工具
Nuxt 支持 Vite、Webpack 两种打包工具,默认使用 Vite。我们可以根据项目需要选择,设置 builder 即可。
下面配置设置打包工具为 Webpack:
arduino
复制代码export default defineNuxtConfig({
builder: "webpack"
});
注意:需要安装 @nuxt/webpack-builder。
相应的,如果要修改对应打包工具配置,可以使用 Vite 或 Webpack 选项:
arduino
复制代码export default defineNuxtConfig({
vite: {},
webpack: {}
});
# 配置渲染模式
Nuxt 默认渲染模式是 SSR 模式。
可以通过设置 ssr: false 修改渲染模式为 SPA,nuxt.config.ts:
arduino
复制代码export default defineNuxtConfig({
ssr: false,
})
可以通过设置 nitro.presets 选项修改渲染模式为非 node 模式,nuxt.config.ts:
php
复制代码export default defineNuxtConfig({
nitro: {
preset: 'vercel'
},
})
# 端口号
配置了端口号为 8080,避免和其他本地服务端口冲突,package.json:
json
复制代码{
"scripts": {
"dev": "nuxt dev --port=8080"
}
}
# 环境变量
Nuxt 配置中有一个运行时配置 runtimeConfig 可用于对外暴露值,就像环境变量、秘钥等。默认情况下这些 key 只能用于服务端,除非把 key 存储在 runtimeConfig.public 字段中。跟 appConfig 比起来,它们只能在 nuxt.config 中定义,值可以被环境变量覆盖,且不能在运行时修改。
添加 runtimeConfig,nuxt.config.ts:
arduino
复制代码export default defineNuxtConfig({
runtimeConfig: {
// 只能用于服务端的 keys
apiSecret: '123',
// 可用于客户端的 keys
public: {
apiBase: '/api'
}
}
})
访问runtimeConfig,修改 config.vue:
xml
复制代码<template>
<div :class="{ dark: appConfig.theme.dark }">
<!-- ... -->
<!-- 客户端只能访问public里面的key -->
<p
class="bg-blue-300 dark:bg-slate-600 dark:text-slate-200"
@click="appConfig.title = 'hello'"
>
runtimeConfig.public.apiBase: {{ runtimeConfig.public.apiBase }}
</p>
<!-- ... -->
</div>
</template>
<script setup lang="ts">
const runtimeConfig = useRuntimeConfig()
console.log('Runtime config:', runtimeConfig)
// 只在服务端才能输出
if (process.server) {
console.log('API secret:', runtimeConfig.apiSecret)
}
</script>
服务端效果如下:apiBase 和 apiSecret 都可以访问:

客户端效果如下:只有 apiBase:

# 范例:环境变量配置
结合 dotenv 可以配置环境变量并覆盖 runtimeConfig 中的对应项,创建 .env 文件:
ini
复制代码NUXT_API_SECRET=api_secret_token
NUXT_PUBLIC_API_BASE=https://nuxt3.cn
注意
NUXT,NUXT_PUBLIC前缀,以及驼峰转换对应关系。
现在再看效果:


# 自动导入
该选项主要设置自动导入,例如前面的 store 目录就可以通过配置该选项,避免用户每次使用时手动导入。nuxt.config.ts:
php
复制代码export default defineNuxtConfig({
imports: {
dirs: ['store']
},
}
现在 [id].vue 和 login.vue 中都不需要手动导入 useUser 了!
# 配置 Meta 信息
我们常常因为 SEO 等需求需要修改页头等 Meta 信息,Nuxt 提供三种修改 Meta 信息的方法:
- 全局配置页头信息;
- composables 方法;
- 内置组件修改。
# 全局配置页头信息
通过 app.head 可以全局配置网站页头信息:
php
复制代码export default defineNuxtConfig({
app: {
head: {
charset: 'utf-8', // 快捷方式
viewport: 'width=device-width, initial-scale=1', // 快捷方式
title: 'My App',
meta: [
{ name: 'description', content: 'My amazing site.' },
{ name: 'charset', content: 'utf-8' },
],
"link": [],
"style": [],
"script": []
}
}
})
# 范例:设置博客范例页头信息
我们在 nuxt.config.ts 中配置整站的描述和关键字:
php
复制代码export default defineNuxtConfig({
app: {
head: {
title: "村长的技术空间",
meta: [
{ name: "description", content: "专注于前端技术分享" },
{ name: "keywords", content: "nuxt,vue,ts,frontend" },
]
},
}
})
效果如下:


# composables 方法
Nuxt 提供了一个 useHead() 可以在组件内修改 meta 信息:
php
复制代码<script setup lang="ts">
useHead({
title: 'My App',
meta: [
{ name: 'description', content: 'My amazing site.' }
],
bodyAttrs: {
class: 'test'
},
script: [ { children: 'console.log('Hello world')' } ]
})
</script>
# 范例:设置各子页面标题
设置首页标题,index.vue
css
复制代码useHead({
title: '文章列表'
})
这样虽然生效,但之前设置的网站名称被覆盖了:

可以设置标题模板解决此问题,app.vue:
xml
复制代码<script setup lang="ts">
useHead({
titleTemplate: (s) => {
return s ? `${s} - 村长的技术空间` : "村长的技术空间";
},
});
</script>
问题解决了:

再去详情页设置页面标题,[id].vue:
csharp
复制代码const route = useRoute();
// 设置为当前文章id
useHead({
title: route.params.id as string
});
效果如下:

当然也可以设置为文章标题:
kotlin
复制代码const { data, pending, error } = await useAsyncData("post", fetchPost);
// 设置为文章结果
useHead({
title: data.value?.title
});
效果如下:

# 内置组件修改
Nuxt 还提供了多种组件可以在模板中设置具体页面页头信息:<Title>, <Base>, <NoScript>, <Style>, <Meta>, <Link>, <Body>, <Html> , <Head>,像下面这样使用:
xml
复制代码<script setup>
const title = ref('Hello World')
</script>
<template>
<div>
<Head>
<Title>{{ title }}</Title>
<Meta name="description" :content="title" />
</Head>
</div>
</template>
这更符合大家直觉了!在 [id].vue 中试一下:效果如初~
xml
复制代码<template>
<div class="p-5">
<Head>
<Title>{{ data?.title }}</Title>
</Head>
<!-- ... -->
</div>
</template>
# 总结
到这里,开发中常见选项设置就跟大家讨论完毕了。我们不太可能在一节中覆盖全部内容,但是我们演示这些都是最常见的配置需求,可以解决大家大部分问题。更多细节还需要大家多多阅读文档 (opens new window)。